	.orig	0x400
	xor	t0,t0,t0
Keys:
	lw	t1,0xf000(t0)	;  Gets 000F when no KEY is pushed, 0000 when all are
	xori	t1,t1,0xF	;  Flip KEY bits to make it easier to understand
	sw	t1,0xf800(t0)	;  Display KEY status
	addi	t2,t0,0xF
	bne	t1,t2,Keys	;  Keep displaying until all KEY are pushed together
	addi	t1,t0,1
	sw	t1,0xf800(t0)	;  Display 0001
NoKeys:
	lw	t1,0xf000(t0)
	xori	t1,t1,0xF
	bne	t1,t0,NoKeys	;  Wait until all KEY released
	
	addi	t1,t0,2
	sw	t1,0xf800(t0)	;  Display 0002, wait for KEY[0] to be pressed
PosKey:
	lw	t2,0xf000(t0)
	andi	t2,t2,0x1
	xori	t2,t2,1
	beqz	t2,PosKey
	addi	t1,t1,1
	sw	t1,0xf800(t0)	;  Display 0003, wait until KEY[0] released
	addi	t3,t0,1
NegKey:
	lw	t2,0xf000(t0)
	and	t2,t2,t3
	xor	t2,t2,t3
	beq	t2,t3,NegKey

	addi	s0,t0,4		;  Test 4
	lw	t2,ffour(t0)
	andi	t3,t2,0xff
	beq	s0,t3,SkipE4	;  If 8 lowermost bits are 4, it's OK
	addi	a0,s0,0		;  Error number to display
	addi	a1,t3,0		;  Value we got (should be 0004)
	beq	a0,a0,Error	;  Display error
SkipE4:
	addi	s0,s0,1		;  Test 5
	jrl	rv,TestJRL(t0)	;  Jump, RV should become equal to RetLbl
RetLbl:
	addi	a0,s0,0		; Didn't jump, error 5
	beq	a0,a0,Error	; Display error
TestJRL:
	addi	s0,s0,1		;  Test 6
	addi	t1,t0,RetLbl
	addi	a0,s0,0		; Error code
	addi	a1,rv,0		; Vale of RV
	bne	rv,t1,Error	; Display error if RV is wrong
	addi	s0,s0,1		; Test 7
	addi	t2,t0,TestJRL
	sub	t3,t2,rv	;  TestJRL-RetLbl should be 8
	addi	t1,t0,8
	addi	a0,s0,0		; Error code
	addi	a1,t3,0		; Value of difference
	bne	t3,t1,Error	; Display error difference not 8

	addi	s0,s0,1		; Test 8
	addi	t1,t0,8
	subi	t1,t1,10	; Should now be -2
	addi	t2,r0,-2
	addi	a0,s0,0		;  Error code
	addi	a1,t1,0		;  Value of RV
	bne	t1,t2,Error	;  Display error if RV is wrong
	
	addi	t1,t0,17
	addi	t2,t0,100
	addi	t3,t0,117

	addi	s0,s0,1		; Test 9
	addi	a0,s0,0		; Error code
	add	a1,t1,t2	; Should be 117
	bne	a1,t3,Error	; Display error is not

	addi	s0,s0,1		; Test A
	addi	a0,s0,0		; Error code
	sub	a1,t3,t1	; Should be 100
	bne	a1,t2,Error	; Display error if not

	addi	s0,s0,1		; Test B
	addi	a0,s0,0		; Error code
	lt	a1,t1,t2	; Should be 1
	subi	a2,a1,1
	bnez	a2,Error	; Display error if not

	addi	s0,s0,1		; Test C
	addi	a0,s0,0		; Error code
	lt	a1,t2,t1	; Should be 0
	bnez	a1,Error	; Display error if not

	addi	s0,s0,1		; Test D
	addi	a0,s0,0		; Error code
	lt	a1,t2,t2	; Should be 0
	bnez	a1,Error	; Display error if not
	 
	addi	s0,s0,1		; Test E
	addi	a0,s0,0		; Error code
	le	a1,t1,t2	; Should be 1
	subi	a2,a1,1
	bnez	a2,Error	; Display error if not

	addi	s0,s0,1		; Test F
	addi	a0,s0,0		; Error code
	le	a1,t2,t1	; Should be 0
	bnez	a1,Error	; Display error if not

	addi	s0,s0,1		; Test 0x10
	addi	a0,s0,0		; Error code
	le	a1,t2,t2	; Should be 1
	beqz	a1,Error	; Display error if not
	 
	addi	t1,t0,-17
	addi	t2,t0,100
	addi	t3,t0,117

	addi	s0,s0,1		; Test 0x11
	addi	a0,s0,0		; Error code
	add	a1,t3,t1	; Should be 100
	bne	a1,t2,Error	; Display error is not

	addi	s0,s0,1		; Test 0x12
	addi	a0,s0,0		; Error code
	sub	a1,t2,t1	; Should be 117
	bne	a1,t3,Error	; Display error if not

	addi	s0,s0,1		; Test 0x13
	addi	a0,s0,0		; Error code
	lt	a1,t1,t2	; Should be 1
	subi	a2,a1,1
	bnez	a2,Error	; Display error if not

	addi	s0,s0,1		; Test 0x14
	addi	a0,s0,0		; Error code
	lt	a1,t2,t1	; Should be 0
	bnez	a1,Error	; Display error if not

	addi	s0,s0,1		; Test 0x15
	addi	a0,s0,0		; Error code
	lt	a1,t1,t1	; Should be 0
	bnez	a1,Error	; Display error if not
	 
Done:
	addi	a0,s0,0xD000
DLoop:	
	sw	a0,0xf800(t0)
	beq	a0,a0,DLoop
Error:	
	ADDI	A0,A0,0xE000
ELoop:
	lw	t1,0xf000(t0)
	andi	t1,t1,0x1
	xori	t1,t1,1
	bnez	t1,ErrVal
	SW	A0,0xf800(R0)
	BEQ	A0,A0,ELoop
ErrVal:
	SW	A1,0xf800(R0)
	BEQ	A1,A1,ELoop
ffour:	
	.word	0xffff0004
neg1:
	.word	-1
